home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / util / packable.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  7KB  |  164 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from primitives import to_hex
  5. from struct import Struct
  6. from itertools import izip
  7. from logging import getLogger
  8. log = getLogger('packable')
  9.  
  10. def debugline(fc):
  11.     return '  File "%s", line %d, in %s' % (fc.co_filename, fc.co_firstlineno, fc.co_name)
  12.  
  13.  
  14. class PackableMeta(type):
  15.     
  16.     def __new__(meta, classname, bases, newattrs):
  17.         cls = super(PackableMeta, meta).__new__(meta, classname, bases, newattrs)
  18.         if 'fmt' not in newattrs:
  19.             return cls
  20.         
  21.         byteorder = newattrs.pop('byteorder', '!')
  22.         fmt = newattrs.pop('fmt')
  23.         __slots__ = list(fmt[::2])
  24.         _struct = Struct(byteorder + ''.join(fmt[1::2]))
  25.         _invars = newattrs.pop('invars', [])
  26.         if not isinstance(_invars, (list, tuple)):
  27.             _invars = [
  28.                 _invars]
  29.         
  30.         fmts = ''.join((lambda .0: for i, j in .0:
  31. '\t%s\t\t%s\n' % (i, j))(izip(fmt[::2], fmt[1::2])))
  32.         cls.__doc__ = 'Constructs a %s, taking sequential arguments in the order they were\nspecified by the format description (or named keyword arguments!):\n\n%s' % (classname, fmts)
  33.         
  34.         def checkinvars(cls, o):
  35.             for invar in cls._invars:
  36.                 if not invar(o):
  37.                     fc = invar.func_code
  38.                     raise AssertionError('Invariant failed after unpacking:\n%s' % debugline(fc))
  39.                     continue
  40.             
  41.  
  42.         
  43.         def unpack(cls, data):
  44.             sz = cls._struct.size
  45.             o = cls(*cls._struct.unpack(data[:sz]))
  46.             
  47.             try:
  48.                 checkinvars(cls, o)
  49.             except AssertionError:
  50.                 log.error('wrong data: %s', to_hex(data))
  51.                 raise 
  52.  
  53.             return (o, data[sz:])
  54.  
  55.         unpack = (classmethod,)(unpack)
  56.         
  57.         def pack(self):
  58.             checkinvars(self.__class__, self)
  59.             attrs = [ getattr(self, field) for field in self.__slots__ ]
  60.             return self._struct.pack(*attrs)
  61.  
  62.         
  63.         def __eq__(self, other):
  64.             for attr in self.__slots__:
  65.                 if getattr(other, attr, sentinel) != getattr(self, attr):
  66.                     return False
  67.                     continue
  68.             
  69.             return True
  70.  
  71.         
  72.         __len__ = lambda self: self._struct.size
  73.         
  74.         __iter__ = lambda self: (lambda .0: for s in .0:
  75. (s, getattr(self, s)))(self.__slots__)
  76.  
  77.         __str__ = pack
  78.         localdict = locals()
  79.         classattrs = '__slots__ _struct pack unpack __len__\n                        _invars __iter__ __str__ __eq__'.split()
  80.         for a in classattrs:
  81.             setattr(cls, a, localdict[a])
  82.         
  83.         return cls
  84.  
  85.  
  86.  
  87. class Packable(object):
  88.     __metaclass__ = PackableMeta
  89.     
  90.     def __init__(self, *a, **kw):
  91.         i = -1
  92.         for i, d in enumerate(a):
  93.             setattr(self, self.__slots__[i], d)
  94.         
  95.         for f in self.__slots__[i + 1:]:
  96.             setattr(self, f, 0)
  97.         
  98.         for k in kw:
  99.             setattr(self, k, kw[k])
  100.         
  101.  
  102.     
  103.     def __repr__(self):
  104.         return '<%s %s>' % (type(self).__name__, ' '.join((lambda .0: for i in .0:
  105. '%s=%r' % i)(self)))
  106.  
  107.  
  108. from math import log as _log, floor, ceil
  109.  
  110. def num_bits(i):
  111.     return floor(_log(i, 2)) + 1
  112.  
  113.  
  114. def num_bytes(i):
  115.     if i in (0, 1):
  116.         return 1
  117.     else:
  118.         return int(ceil(pow(2, num_bits(num_bits(i) - 1)) / 8))
  119.  
  120.  
  121. def make_packable(info):
  122.     (names, values) = zip(*sorted(info, key = (lambda x: type(x[1]))))
  123.     type_size = {
  124.         str: (lambda s: len(s)),
  125.         unicode: (lambda u: 2 * len(u)),
  126.         int: (lambda i: pow(2, num_bits(num_bits(i) - 1)) / 8),
  127.         bool: (lambda b: 0) }
  128.     
  129.     get_size = lambda x: type_size[type(x)](x)
  130.     sizes = [ get_size(v) for v in values ]
  131.     ints = bools_to_ints(filter((lambda x: type(x) is bool), values))
  132.     size_in_bytes = sum(sizes) + len(ints) * 4
  133.  
  134.  
  135. def bools_to_ints(bools):
  136.     nums = []
  137.     num_ints = ceil(len(bools) / 32)
  138.     for i in range(num_ints):
  139.         num = 0
  140.         for i in range(len(bools[i * 32:(i + 1) * 32])):
  141.             num |= bools[i] * pow(2, i % 32)
  142.         
  143.         nums.append(num)
  144.     
  145.     return nums
  146.  
  147.  
  148. def main():
  149.     
  150.     class Meep(Packable):
  151.         fmt = ('version', '4s', 'length', 'H', 'name', '3s')
  152.         invars = [
  153.             (lambda o: o.version == 'OFT2')]
  154.  
  155.     m = Meep('OFT2', 2, 'abc')
  156.     print repr(str(Meep.unpack(m.pack())[0]))
  157.     print m.__class__.__name__
  158.     print m.__doc__
  159.     print repr(m)
  160.  
  161. if __name__ == '__main__':
  162.     main()
  163.  
  164.